package com.hna.face.security.ssl;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.InputStreamReader;
import java.security.KeyFactory;
import java.security.KeyStore;
import java.security.PrivateKey;
import java.security.SecureRandom;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import java.security.interfaces.RSAPrivateKey;
import java.security.spec.PKCS8EncodedKeySpec;

import javax.net.ssl.KeyManagerFactory;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSocketFactory;
import javax.net.ssl.TrustManagerFactory;

import org.apache.commons.codec.binary.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.core.io.ClassPathResource;

import com.hna.face.mqtt.MqttService;

/**
 * Created by hna on 2018/3/27.
 */
public class SSLUtils {
	
	private final static Logger log = LoggerFactory.getLogger(SSLUtils.class);

	public SSLSocketFactory getSSLSocktet(String caPath, String crtPath, String keyPath, String password) throws Exception{
		log.info("caPath:"+caPath);
		log.info("crtPath:"+crtPath);
		log.info("keyPath:"+keyPath);
		
		CertificateFactory cAf = CertificateFactory.getInstance("X.509");
		FileInputStream caIn = new FileInputStream(caPath);
		X509Certificate ca = (X509Certificate) cAf.generateCertificate(caIn);
		KeyStore caKs = KeyStore.getInstance("JKS");
		caKs.load(null, null);
		caKs.setCertificateEntry("ca-certificate", ca);
		TrustManagerFactory tmf = TrustManagerFactory.getInstance("PKIX");
		tmf.init(caKs);

		CertificateFactory cf = CertificateFactory.getInstance("X.509");
		FileInputStream crtIn = new FileInputStream(crtPath);
		X509Certificate caCert = (X509Certificate) cf.generateCertificate(crtIn);

		crtIn.close();
		// client key and certificates are sent to server so it can authenticate
		KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType());
		//      ks.load(caIn,password.toCharArray());
		ks.load(null, null);
		ks.setCertificateEntry("certificate", caCert);
		ks.setKeyEntry("private-key", getPrivateKey(keyPath), password.toCharArray(),
				new java.security.cert.Certificate[]{caCert}  );
		KeyManagerFactory kmf = KeyManagerFactory.getInstance("PKIX");
		kmf.init(ks, password.toCharArray());
		//      keyIn.close();

		// finally, create SSL socket factory
		SSLContext context = SSLContext.getInstance("TLSv1");//"SSLv3"

		context.init(kmf.getKeyManagers(),tmf.getTrustManagers(), new SecureRandom());
		return context.getSocketFactory();

	}

	private PrivateKey getPrivateKey(String path) throws Exception{
		Base64 base64=new Base64();
		byte[] buffer=   base64.decode(getPem(path));

		PKCS8EncodedKeySpec keySpec= new PKCS8EncodedKeySpec(buffer);
		KeyFactory keyFactory= KeyFactory.getInstance("RSA");
		log.info("getPrivateKey:"+keyFactory);
		return (RSAPrivateKey) keyFactory.generatePrivate(keySpec);

	}

	private String getPem(String path) throws Exception{
		FileInputStream fin=new FileInputStream(path);
		BufferedReader br= new BufferedReader(new InputStreamReader(fin));
		String readLine= null;
		StringBuilder sb= new StringBuilder();
		while((readLine= br.readLine())!=null){
			if(readLine.charAt(0)=='-'){
				continue;
			}else{
				sb.append(readLine);
				sb.append('\r');
			}
		}
		fin.close();
		return sb.toString();
	}
}
